﻿using Basic.HrGatewayModular.Interface;
using Basic.HrGatewayModular.Model.EmpLogin;
using Basic.HrRemoteModel.EmpLogin.Model;
using Lazy.Captcha.Core.Interface;
using WeDonekRpc.Helper;
using WeDonekRpc.HttpApiGateway.Interface;
using WeDonekRpc.HttpApiGateway.Response;

namespace Basic.HrGatewayModular.Extend
{
    internal class LoginService : ILoginService
    {
        private readonly ILoginVerService _LoginVer;

        private readonly IEmpLoginService _EmpLogin;
        private readonly ILoginVerCode _VerCode;
        private readonly IIpLimitService _IpLimit;
        private static readonly string _IpLimitKey = "LoginVer";
        public LoginService ( ILoginVerService loginVer,
            IEmpLoginService empLogin,
            IIpLimitService ipLimit,
            ILoginVerCode verCode )
        {
            this._IpLimit = ipLimit;
            this._LoginVer = loginVer;
            this._EmpLogin = empLogin;
            this._VerCode = verCode;
        }
        public bool CheckIsVerCode ( string loginName )
        {
            return this._LoginVer.CheckIsVerCode(loginName);
        }
        public IResponse CreateCode ( string loginName )
        {
            byte[] img = this._VerCode.Generate(loginName);
            return new StreamResponse(img, "verCode.png");
        }
        public EmpLoginRes EmpPwdLogin ( UI_EmpPwdLogin login, LoginState state )
        {
            if ( this._LoginVer.CheckVerState(login.LoginName) == false || login.VerCode.IsNotNull() )
            {
                this._VerCode.Validate(login.LoginName, login.VerCode);
            }
            this._IpLimit.CheckIsLimit(_IpLimitKey, state.LoginIp);
            try
            {
                EmpLoginRes res = this._EmpLogin.EmpPwdLogin(login.LoginName, login.Password, state);
                this._LoginVer.Clear(login.LoginName);
                return res;
            }
            catch ( ErrorException e )
            {
                if ( this._LoginVer.CheckIsVer(e) )
                {
                    this._IpLimit.LimitTally(_IpLimitKey, state.LoginIp);
                    if ( this._LoginVer.LoginFail(login.LoginName) )
                    {
                        throw new ErrorException(e.ErrorCode, "verCode:true");
                    }
                }
                throw;
            }
        }
    }
}
